/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/* eslint-disable prefer-arrow-callback */
(function scrollSpy() {
    const OFFSET = 10;
    let timer;
    let headingsCache;
    const findHeadings = function findHeadings() {
        return headingsCache || document.querySelectorAll(".toc-headings > li > a");
    };
    const onScroll = function onScroll() {
        if (timer) {
            // throttle
            return;
        }
        timer = setTimeout(function() {
            timer = null;
            let activeNavFound = false;
            const headings = findHeadings(); // toc nav anchors
            /**
             * On every call, try to find header right after  <-- next header
             * the one whose content is on the current screen <-- highlight this
             */
            for (let i = 0; i < headings.length; i++) {
                // headings[i] is current element
                // if an element is already active, then current element is not active
                // if no element is already active, then current element is active
                let currNavActive = !activeNavFound;
                /**
                 * Enter the following check up only when an active nav header is not yet found
                 * Then, check the bounding rectangle of the next header
                 * The headers that are scrolled passed will have negative bounding rect top
                 * So the first one with positive bounding rect top will be the nearest next header
                 */
                if (currNavActive && i < headings.length - 1) {
                    const heading = headings[i + 1];
                    const next = decodeURIComponent(heading.href.split("#")[1]);
                    const nextHeader = document.getElementById(next);

                    if (nextHeader) {
                        const top = nextHeader.getBoundingClientRect().top;
                        currNavActive = top > OFFSET;
                    } else {
                        console.error("Can not find header element", {
                            id: next,
                            heading
                        });
                    }
                }
                /**
                 * Stop searching once a first such header is found,
                 * this makes sure the highlighted header is the most current one
                 */
                if (currNavActive) {
                    activeNavFound = true;
                    headings[i].classList.add("active");
                } else {
                    headings[i].classList.remove("active");
                }
            }
        }, 100);
    };

    document.addEventListener("scroll", onScroll);
    document.addEventListener("resize", onScroll);
    document.addEventListener("DOMContentLoaded", function() {
        // Cache the headings once the page has fully loaded.
        headingsCache = findHeadings();
        onScroll();
    });
})();
